package com.idea.relax.tool.core.tree;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author azhao
 */
public class ListTree<T> {
    private final Logger logger = LoggerFactory.getLogger(ListTree.class);
    protected Field id;
    protected Field parentId;
    protected Field children;
    protected Field level;
    protected List<Field> otherFields = new ArrayList<>();
    protected List<Field> treeFields = new ArrayList<>();
    protected List<T> list = new ArrayList<>();
    protected int levelNumber = 1;

    protected void setOtherFields(T t, T obj) {
        for (Field field : otherFields) {
            try {
                field.set(obj, field.get(t));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    protected void setTreeFields(T t, T obj) {
        for (Field field : treeFields) {
            try {
                field.set(obj, field.get(t));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    protected T cloneObject(T t) {
		T o = null;
//		try {
////			o = (T) ReflectUtil.newInstance(t.getClass());
//		} catch (InstantiationException e) {
//			throw new RuntimeException(e);
//		} catch (IllegalAccessException e) {
//			throw new RuntimeException(e);
//		}
		setTreeFields(t, o);
        setOtherFields(t, o);
        return o;
    }

    protected void init(List<T> source) {
        Field[] fields = source.get(0).getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(TreeId.class)) {
                id = field;
                treeFields.add(field);
                continue;
            }
            if (field.isAnnotationPresent(TreeParentId.class)) {
                parentId = field;
                treeFields.add(field);
                continue;
            }
            if (field.isAnnotationPresent(TreeChildren.class)) {
                children = field;
                treeFields.add(field);
                continue;
            }
            if (field.isAnnotationPresent(Level.class)) {
                level = field;
                treeFields.add(field);
                continue;
            }
            otherFields.add(field);
        }
    }

    protected boolean check(List<T> source) {
        if (CollectionUtils.isEmpty(source)) {
            logger.info("list 为空");
            return true;
        }
        T t = source.get(0);
        if (t.getClass().getAnnotation(TreeNode.class) == null) {
            logger.info("@TreeNode注解不存在");
            return true;
        }

        List<Field> idFields = new ArrayList<>();
        List<Field> pidFields = new ArrayList<>();
        List<Field> childrenFields = new ArrayList<>();
        Field[] fields = t.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(TreeId.class)) {
                idFields.add(field);
            }
            if (field.isAnnotationPresent(TreeParentId.class)) {
                pidFields.add(field);
            }
            if (field.isAnnotationPresent(TreeChildren.class)) {
                childrenFields.add(field);
            }
        }
        if (idFields.size() != 1) {
            logger.info("@TreeId注解只能有一个");
            return true;
        }
        if (pidFields.size() != 1) {
            logger.info("@TreeParentId注解只能有一个");
            return true;
        }
        if (childrenFields.size() != 1) {
            logger.info("@TreeChildren注解只能有一个");
            return true;
        }
        return false;
    }
}
